package demo.hdz.mediacodecdecode.filter;

import android.content.Context;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.util.Log;

import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

/**
 * @author hdz
 * @date 2022/05/29 11:43
 */
public class DefaultFilterV3 extends BaseFilter {
    private static final String TAG = "DefaultFilterV3";

    /**
     * 顶点坐标
     * (x,y,z)
     */
    private static final float[] VERTEX_COORDINATE = {
            //右上
            1f, 1f, 0f,

            //右下
            1f, -1f, 0f,

            //左上
            -1f, 1f, 0f,

            //左下
            -1f, -1f, 0f
    };

    /**
     * 纹理坐标
     * (s,t)
     */
    private static final float[] TEXTURE_COORDINATE = {
            1f, 1f,
            1f, 0f,
            0f, 1f,
            0f, 0f
    };

    /**
     * 坐标索引
     */
    private static final short[] COORDINATE_INDEX = {
            //右上三角形
            0, 1, 2,

            //左下三角形
            1, 2, 3
    };


    private int[] mVaoId = new int[1];
    private int[] mVboIds = new int[3];

    private FloatBuffer mVertexBuffer;
    private FloatBuffer mTexVertexBuffer;
    private ShortBuffer mVertexIndexBuffer;
    private int aPositionLocation = -1;
    private int aTextureCoordLocation = -1;
    private int uTextureMatrixLocation = -1;
    private int uTextureSamplerLocation = -1;

    public DefaultFilterV3(Context context) {
        //貌似采用2.0的写法也是可以
        //super(context, "shader/v_default.frag", "shader/f_default.frag");
        super(context, "shader/defaultV3.vert", "shader/defaultV3.frag");
    }

    @Override
    public void init() {
        mVertexBuffer = createBuffer(VERTEX_COORDINATE);
        mTexVertexBuffer = createBuffer(TEXTURE_COORDINATE);
        mVertexIndexBuffer = createBuffer(COORDINATE_INDEX);

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShader.trim());
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShader.trim());
        int mShaderProgram = linkProgram(vertexShader, fragmentShader);

        aPositionLocation = GLES20.glGetAttribLocation(mShaderProgram, "aPosition");
        aTextureCoordLocation = GLES20.glGetAttribLocation(mShaderProgram, "aTextureCoordinate");
        uTextureMatrixLocation = GLES20.glGetUniformLocation(mShaderProgram, "uTextureMatrix");
        uTextureSamplerLocation = GLES20.glGetUniformLocation(mShaderProgram, "uTextureSampler");

        // 创建并绑定VAO
        GLES30.glGenVertexArrays(1, mVaoId, 0);
        GLES30.glBindVertexArray(mVaoId[0]);

        // 在绑定 VAO 之后，操作 VBO ，当前 VAO 会记录 VBO 的操作
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVaoId[0]);


        GLES30.glGenBuffers(3, mVboIds, 0);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVboIds[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, VERTEX_COORDINATE.length * 4, mVertexBuffer, GLES30.GL_STATIC_DRAW);
        GLES30.glVertexAttribPointer(aPositionLocation, 3, GLES30.GL_FLOAT, false, 0, 0);
        GLES30.glEnableVertexAttribArray(aPositionLocation);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVboIds[1]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, TEXTURE_COORDINATE.length * 4, mTexVertexBuffer, GLES30.GL_STATIC_DRAW);
        GLES30.glVertexAttribPointer(aTextureCoordLocation, 2, GLES30.GL_FLOAT, false, 0, 0);
        GLES30.glEnableVertexAttribArray(aTextureCoordLocation);

        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, mVboIds[2]);
        GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER, COORDINATE_INDEX.length * 2, mVertexIndexBuffer, GLES30.GL_STATIC_DRAW);

        //解绑VAO
        //GLES30.glBindVertexArray(GLES30.GL_NONE);
    }

    @Override
    public void release() {
        //解绑VAO
        GLES30.glBindVertexArray(GLES30.GL_NONE);
    }

    @Override
    public void drawFrame(int textureId, float[] transformMatrix) {
        //激活纹理单元0
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        //会报警告：bindTextureImage: clearing GL error: 0x500
        //GLES20.glActiveTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
        //绑定外部纹理到纹理单元0
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
        //将此纹理单元床位片段着色器的uTextureSampler外部纹理采样器
        GLES20.glUniform1i(uTextureSamplerLocation, 0);

        //将纹理矩阵传给片段着色器
        GLES20.glUniformMatrix4fv(uTextureMatrixLocation, 1, false, transformMatrix, 0);

        //绑定VAO
        //GLES30.glBindVertexArray(mVaoId[0]);

        // 绘制
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, COORDINATE_INDEX.length, GLES20.GL_UNSIGNED_SHORT, 0);

        //解绑VAO
        //GLES30.glBindVertexArray(0);
    }
}
